/**
 * 根据正则表达式，设计自定义处理表单输入规则的指令
 */
const inputNumber = {
    bind: (el, binding, vnode) => {
        // 定位输入框
        let input = el.tagName === 'INPUT' ? el : vnode.elm.children[0];
        // compositionstart -> 开始新的输入合成时会触发
        input.addEventListener('compositionstart', (_) => {
            vnode.inputLocaking = true;
        });
        // compostitonend -> 合成完成或取消时触发
        input.addEventListener('compostitonend', (_) => {
            vnode.inputLocaking = false;
            input.dispatchEvent(new Event('input'));
        });
        input.addEventListener('input', (_) => {
            if (vnode.inputLocaking) return;

            let oldValue = input.value;
            let newValue = input.value;

            if (binding.modifiers.float) {
                // 清除数字和‘.’以外的字符
                newValue = newValue.replace(/[^\d.]/g, '');
                // 只保留第一个‘.’，清除多余的
                newValue = newValue.replace(/\.{2,}/g, '.');
                // 第一个字符如果是‘.’，补充前缀0
                newValue = newValue.replace(/^\./g, '0.');
                // 0开头的只有保留第一个0，清除多余的
                newValue = newValue.replace(/^0{2,}/g, '0');
                // 两位数以上不能0开头
                if (/^0\d+/.test(newValue)) {
                    newValue = newValue.slice(1);
                }
                // 保证‘.’只出现一次，而不能出现两次以上
                newValue = newValue.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');

                // 保留几位小数
                if (typeof binding.value !== 'undefined') {
                    // 期望保留的最大小数位数
                    let poinKeep = 0;
                    if (typeof binding.value === 'string' || typeof binding.value === 'number') {
                        pointKeep = parseInt(binding.value);
                    }
                    if (!isNaN(pointKeep)) {
                        if (!Number.isInteger(pointKeep) || pointKeep < 0) {
                            pointKeep = 0;
                        }
                        const str = '^(\\d+)\\.(\\d{' + pointKeep + '}).*$';
                        const reg = new RegExp(str);
                        if (pointKeep === 0) {
                            // 不需要小数点
                            newValue = newValue.replace(reg, '$1');
                        } else {
                            // 通过正则表达式保留小数点后指定的位数
                            newValue = newValue.replace(reg, '$1.$2');
                        }
                    }
                }
            } else {
                // 只保留整数
                newValue = newValue.replace(/[^\d]/g, '');
                newValue = newValue ? parseInt(newValue) : '';
            }

            // 判断是否需要更新，避免进入死循环
            if (+newValue !== +oldValue) {
                input.value = newValue;
                input.dispatchEvent(new Event('input'));
            }
        });
    }
};

export default inputNumber;
